在 Laravel 中,路由是定義 URL 請求和決定請求要交給哪個方法去處理邏輯的關鍵。
所有的 Laravel 路由都被定義在 routes 目錄中的不同檔案中,這些檔案會被 Laravel 應用的 App\Providers\RouteServiceProvider
自動解析這些依賴並注入到相應的類中,這使得代碼更加模組化和可測試。
Route::
在 Laravel 中,Route
類用來定義路由,後端只需要提供 HTTP 請求方法、路由 (URI) 和其對應的行為 (閉包),就可以完成基本的路由,以下是建立一個基本路由的流程:
routes/api.php
定義路由,指定對應的 URL 和控制器方法
use Illuminate\Support\Facades\Route;
// 最基本的 Laravel 路由接受一個 URI 和一個閉包
Route::get('/greeting', function () {
return 'Hello World';
});
php artisan serve
讓本地開發伺服器運行只會處理指定的 HTTP 方法 Route::match()
// 只處理 GET 和 POST 兩種 HTTP 請求方法,其餘免談
Route::match(['get', 'post'], '/', function () {
...
});
處理任何類型的 HTTP 請求方法 Route::any()
// 任何類型的 HTTP 請求方法,包括 GET、POST、PUT、PATCH、DELETE、OPTIONS 等都可以呼叫
Route::any('/', function () {
...
});
...URI/{}
在 Laravel 中,通過在路由 URI 中使用花括號 {}
來定義路由參數,這些參數可以在 URI 中的特定段落被使用,例如用戶的 ID、文章的 ID 等。
// {id} 是路由參數,可以在 UserController 的 show 方法中獲取
Route::get('/user/{id}', [UserController::class, 'show']);
...URI/{參數名稱?}
在路由 URI 中的參數 {name?} 中,問號 ?
的存在表示這個參數是可選的。
/**
* 如果沒有提供 {name} 這個參數,則 Laravel 將會將 $name 設置為 null
* 如果提供了 {name} 參數,則其值將被賦給 $name 變數
*/
Route::get('/user/{name?}', function ($name = null) {
return $name;
});
// 定義了預設值為 'kuku'。如果沒有提供 {name} 參數,則 $name 將被設置為 'kuku'
Route::get('/user/{name?}', function ($name = 'kuku') {
return $name;
});
->name('唯一的名字')
給路由指定一個唯一
的名稱,以便在應用中方便地引用:
use App\Http\Controllers\UserProfileController;
Route::get('/user/profile', [UserProfileController::class, 'show'])
->name('profile');
$url = route('profile');
dd($url); // /user/profile
->group(…)
一組路由有共用相同的屬性(如中間件或前綴)的時候,就可以使用 ->group(…)
路由前綴 ->prefix(…)
群組中的每個路由新增給定 URI 的前綴。
路由名稱前綴 Route::name('字串的前綴.')
群組中的每個路由名稱新增給定字串的前綴。
Route::name('admin.')->prefix('admin')->middleware('auth')->group(function () {
// 在這個組中的路由都會應用 'auth' 中間件和 '/admin' 前綴
Route::get('/dashboard', function () {
// 路由 URI:/admin/dashboard
return 'Admin Dashboard';
// 命名路由路由:'admin.dashboard'
})->name('dashboard');
Route::get('/users', function () {
// 路由 URI:/admin/users
return 'Admin Users';
// 命名路由路由:'admin.users'
})->name('users');
});
練習專案中建立一個註冊的 api(包含命名路由),因為規劃未來有登入練習,都是跟認證有關係,所以要有路由組的概念加入
routes/api.php
Route::prefix('auth')->group(function () {
Route::post('/register', function (Request $request) {
return 'register-success';
})->name('auth.register');
Route::post('/login', function (Request $request) {
return 'login-success';
})->name('auth.login');
Route::get('/forget/{account?}', function (Request $request, string $account) {
return 'forget-success';
})->whereAlphaNumeric('account')->name('auth.forget');
});
php artisan serve
啟服務確認 portphp artisan route:list
看到路由多一層 apiRouteServiceProvider
執行任務,路由又會根據規則來判斷要把這個請求分配給哪一個控制器的哪一個方法來處理,打開檔案可以看到 boot()
中設定依據 Kernel.php
的 middleware 分類,個別給不同的路由前綴,因為這裡是 api 所以要加 'api' 這一層
public function boot(): void
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
$this->routes(function () {
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'));
Route::middleware('web')
->group(base_path('routes/web.php'));
});
}
?
,所以帳號如果沒有帶也沒有給預設值的狀態下就會壞掉,必須要加上預設值才能安全過關,修改如下:
Route::get('/forget/{account?}', function (Request $request, string $account = null) {
dump($account);
return $request->user();
})->whereAlphaNumeric('account')->name('auth.forget');
感謝閱讀,這邊提醒一下,如果是用 postman 呼叫 api 出現 404 畫面,請先幫忙確認以下事項:
boot()
方法中有提到有前綴的部分,所以需要多一層,如果太複雜,可以用指令 php artisan route:list
確認路由唷!